package com.bkhech.netty.httpwebsocket.server;

import cn.hutool.core.collection.CollUtil;
import com.bkhech.netty.httpwebsocket.pojo.*;
import io.netty.channel.Channel;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

@Slf4j
public class MessageHandlerStrategy {

    private static final Map<MsgType, Consumer<Request<Message>>> functionMap = new HashMap<>(16);

    static {
        try {
            initConsumerMap();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private static void initConsumerMap() {
        functionMap.put(MsgType.CONNECT_INIT, MessageHandlerStrategy::handleInitMsg);
        functionMap.put(MsgType.KEEPALIVE, MessageHandlerStrategy::handleKeepaliveMsg);
        functionMap.put(MsgType.CHAT, MessageHandlerStrategy::handleChatMsg);
    }

    public static void handleMsgByType(Request<Message> request) {
        final MsgType msgType = request.getMsgType();
        functionMap.get(msgType).accept(request);
    }

    /**
     * 处理第一次的消息
     *
     * @param request
     */
    private static void handleInitMsg(Request<Message> request) {
        Channel currentChannel = request.getChannel();
        String currentChannelId = currentChannel.id().asLongText();
        final Message message = request.getMessage();

        String senderId = message.getSenderId();
        UserChannelCache.putMultiChannels(senderId, currentChannel);
        System.out.println("用户id是：" + senderId + ", 对应的channelList的长度是：" + UserChannelCache.getMultiChannels(senderId).size());
        UserChannelCache.putChannelOfUser(currentChannelId, senderId);
        // 只需给当前客户端发送响应消息
        UserChannelCache.sendToTarget(List.of(currentChannel), Response.success(message.getMsgId(), "channel init success").toJsonStr());
    }

    /**
     * 处理客户端心跳信息
     *
     * @param request
     */
    private static void handleKeepaliveMsg(Request<Message> request) {
        final Message message = request.getMessage();
        UserChannelCache.sendToTarget(List.of(request.getChannel()), Response.success(message.getMsgId(), "pong").toJsonStr());
    }


    /**
     * 处理文字消息类型
     *
     * @param request
     * @return
     */
    private static void handleChatMsg(Request<Message> request) {
        final ChatMessage chatMessage = (ChatMessage) request.getMessage();
        // 可在此处做业务处理逻辑
        String receiverId = chatMessage.getReceiverId();
        final String msg = chatMessage.getMsg();

        //回复消息
        final Response<String> dataContent = Response.success(chatMessage.getMsgId(), "你好，" + msg);

        List<Channel> receiverChannels = UserChannelCache.getMultiChannels(receiverId);
        if (CollUtil.isEmpty(receiverChannels)) {
            // 如果为空则表示断线或者离线状态
            // TODO 离线消息如何处理？
            chatMessage.setIsReceiverOnLine(false);
        } else {
            chatMessage.setIsReceiverOnLine(true);
        }

        UserChannelCache.sendToTarget(receiverChannels, dataContent.toJsonStr());


        String senderId = chatMessage.getSenderId();
        Channel channel = request.getChannel();
        List<Channel> myOtherChannels = UserChannelCache.getMyOtherChannel(senderId, channel.id().asLongText());
        // 给自己的其它同步设备也发送消息，不用发给自己当前的客户端
        UserChannelCache.sendToTarget(myOtherChannels, dataContent.toJsonStr());
    }

}
